package com.anolesoft.yr.mbus.fin.service.impl;

import com.anolesoft.yr.exception.ServiceException;
import com.anolesoft.yr.mbus.fin.dto.FinBillingApplyDTO;
import com.anolesoft.yr.mbus.fin.dto.FinBillingApplyInvoiceDTO;
import com.anolesoft.yr.mbus.fin.entity.FinBillingApplyDO;
import com.anolesoft.yr.mbus.fin.entity.FinBillingApplyInvoiceDO;
import com.anolesoft.yr.mbus.fin.mapper.FinBillingApplyInvoiceMapper;
import com.anolesoft.yr.mbus.fin.service.FinBillingApplyInvoiceService;
import com.anolesoft.yr.util.PageData;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author zhj
 * @date 2020/8/15 13:58
 */
@Service("finBillingApplyInvoiceServiceImpl")
public class FinBillingApplyInvoiceServiceImpl implements FinBillingApplyInvoiceService {
    @Autowired
    private FinBillingApplyInvoiceMapper finBillingApplyInvoiceMapper;

    private void checkUnique(FinBillingApplyInvoiceDTO finBillingApplyInvoice, Boolean isModify) {
        String finBillingApplyUid = finBillingApplyInvoice.getFinBillingApplyUid();
        String invoiceCode = finBillingApplyInvoice.getInvoiceCode();
        String receiptCode = finBillingApplyInvoice.getReceiptCode();
        String objuid = finBillingApplyInvoice.getObjuid();
        if (isModify) {
            if (finBillingApplyInvoiceMapper.checkUniqueForFinBillingApplyUidUpdate(finBillingApplyUid, objuid) > 0) {
                throw new ServiceException("收款开单申请已存在");
            }
            if (finBillingApplyInvoiceMapper.checkUniqueForInvoiceCodeUpdate(invoiceCode, objuid) > 0) {
                throw new ServiceException("发票号已存在");
            }
            if (finBillingApplyInvoiceMapper.checkUniqueForReceiptCodeUpdate(receiptCode, objuid) > 0) {
                throw new ServiceException("收款单号已存在");
            }
        } else {
            if (finBillingApplyInvoiceMapper.checkUniqueForFinBillingApplyUid(finBillingApplyUid) > 0) {
                throw new ServiceException("收款开单申请已存在");
            }
            if (finBillingApplyInvoiceMapper.checkUniqueForInvoiceCode(invoiceCode) > 0) {
                throw new ServiceException("发票号已存在");
            }
            if (finBillingApplyInvoiceMapper.checkUniqueForReceiptCode(receiptCode) > 0) {
                throw new ServiceException("收款单号已存在");
            }
        }
    }

    @Override
    public int create(FinBillingApplyInvoiceDTO finBillingApplyInvoiceDTO) {
        checkUnique(finBillingApplyInvoiceDTO, false);
        return finBillingApplyInvoiceMapper.insert(FinBillingApplyInvoiceDO.builder()
                .invoiceCode(finBillingApplyInvoiceDTO.getInvoiceCode())
                .receiptCode(finBillingApplyInvoiceDTO.getReceiptCode())
                .factoryCode(finBillingApplyInvoiceDTO.getFactoryCode())
                .remark(finBillingApplyInvoiceDTO.getRemark())
                .objuid(finBillingApplyInvoiceDTO.getObjuid())
                .modifyUserUid(finBillingApplyInvoiceDTO.getModifyUserUid())
                .deleteFlag(finBillingApplyInvoiceDTO.getDeleteFlag())
                .createUserUid(finBillingApplyInvoiceDTO.getCreateUserUid())
                .createTime(finBillingApplyInvoiceDTO.getCreateTime())
                .amount(finBillingApplyInvoiceDTO.getAmount())
                .finBillingApplyUid(finBillingApplyInvoiceDTO.getFinBillingApplyUid())
                .modifyTime(finBillingApplyInvoiceDTO.getModifyTime())
                .build());
    }

    @Override
    public int modify(FinBillingApplyInvoiceDTO finBillingApplyInvoiceDTO) {
        checkUnique(finBillingApplyInvoiceDTO, true);
        FinBillingApplyInvoiceDO finBillingApplyInvoiceDO = finBillingApplyInvoiceMapper.selectOneById(finBillingApplyInvoiceDTO.getObjuid());
        if (finBillingApplyInvoiceDO == null) {
            finBillingApplyInvoiceDO = FinBillingApplyInvoiceDO.builder().build();
        }
        finBillingApplyInvoiceDO.setInvoiceCode(finBillingApplyInvoiceDTO.getInvoiceCode());
        finBillingApplyInvoiceDO.setReceiptCode(finBillingApplyInvoiceDTO.getReceiptCode());
        finBillingApplyInvoiceDO.setFactoryCode(finBillingApplyInvoiceDTO.getFactoryCode());
        finBillingApplyInvoiceDO.setRemark(finBillingApplyInvoiceDTO.getRemark());
        finBillingApplyInvoiceDO.setObjuid(finBillingApplyInvoiceDTO.getObjuid());
        finBillingApplyInvoiceDO.setModifyUserUid(finBillingApplyInvoiceDTO.getModifyUserUid());
        finBillingApplyInvoiceDO.setDeleteFlag(finBillingApplyInvoiceDTO.getDeleteFlag());
        finBillingApplyInvoiceDO.setCreateUserUid(finBillingApplyInvoiceDTO.getCreateUserUid());
        finBillingApplyInvoiceDO.setCreateTime(finBillingApplyInvoiceDTO.getCreateTime());
        finBillingApplyInvoiceDO.setAmount(finBillingApplyInvoiceDTO.getAmount());
        finBillingApplyInvoiceDO.setFinBillingApplyUid(finBillingApplyInvoiceDTO.getFinBillingApplyUid());
        finBillingApplyInvoiceDO.setModifyTime(finBillingApplyInvoiceDTO.getModifyTime());

        return finBillingApplyInvoiceMapper.update(finBillingApplyInvoiceDO);
    }

    @Override
    public int remove(String id) {
        return finBillingApplyInvoiceMapper.delete(id);
    }

    @Override
    public int removeBatch(List<String> ids) {
        int res = 0;
        for (String id : ids) {
            res += finBillingApplyInvoiceMapper.delete(id);
        }
        return res;
    }

    @Override
    public List<FinBillingApplyInvoiceDTO> selectAll() {
        return finBillingApplyInvoiceMapper.selectAll().stream().map(t -> do2dto(t)).collect(Collectors.toList());
    }

    private FinBillingApplyInvoiceDTO do2dto(FinBillingApplyInvoiceDO t) {
        FinBillingApplyDO finBillingApplyDO = t.getBillingApply();

        FinBillingApplyDTO finBillingApplyDTO = null;
        if (finBillingApplyDO != null) {
            finBillingApplyDTO = FinBillingApplyDTO.builder()
                    .objuid(finBillingApplyDO.getObjuid())
                    .invoiceState(finBillingApplyDO.getInvoiceState())
                    .contractCode(finBillingApplyDO.getContractCode())
                    .billingCode(finBillingApplyDO.getBillingCode())
                    .factoryCode(finBillingApplyDO.getFactoryCode())
                    .modifyTime(finBillingApplyDO.getModifyTime())
                    .remark(finBillingApplyDO.getRemark())
                    .modifyUserUid(finBillingApplyDO.getModifyUserUid())
                    .deleteFlag(finBillingApplyDO.getDeleteFlag())
                    .createUserUid(finBillingApplyDO.getCreateUserUid())
                    .createTime(finBillingApplyDO.getCreateTime())
                    .amount(finBillingApplyDO.getAmount())
                    .build();
        } else {
            finBillingApplyDTO = FinBillingApplyDTO.builder().build();
        }
        return FinBillingApplyInvoiceDTO.builder()
                .amount(t.getAmount())
                .createTime(t.getCreateTime())
                .createUserUid(t.getCreateUserUid())
                .deleteFlag(t.getDeleteFlag())
                .factoryCode(t.getFactoryCode())
                .finBillingApplyUid(t.getFinBillingApplyUid())
                .invoiceCode(t.getInvoiceCode())
                .modifyTime(t.getModifyTime())
                .modifyUserUid(t.getModifyUserUid())
                .objuid(t.getObjuid())
                .receiptCode(t.getReceiptCode())
                .remark(t.getRemark())
                .billingApply(finBillingApplyDTO)
                .build();
    }

    @Override
    public PageData<List<FinBillingApplyInvoiceDTO>> selectAll(Integer limit, Integer curr) {
        Page<FinBillingApplyInvoiceDO> page = new Page<>(curr, limit);
        List<FinBillingApplyInvoiceDO> finBillingApplyInvoiceDOs = finBillingApplyInvoiceMapper.selectPageAll(page);
        List<FinBillingApplyInvoiceDTO> finBillingApplyDTOs = finBillingApplyInvoiceDOs.stream().map(t -> do2dto(t)).collect(Collectors.toList());
        return new PageData<>(((int) page.getTotal()), finBillingApplyDTOs);
    }

    @Override
    public Optional<FinBillingApplyInvoiceDTO> selectOneById(String id) {
        FinBillingApplyInvoiceDO finBillingApplyInvoiceDO = finBillingApplyInvoiceMapper.selectOneById(id);
        if (finBillingApplyInvoiceDO != null) {
            return Optional.of(do2dto(finBillingApplyInvoiceDO));
        }
        return Optional.empty();
    }

    @Override
    public List<FinBillingApplyInvoiceDTO> selectList(FinBillingApplyInvoiceDTO finBillingApplyInvoiceDTO) {
        FinBillingApplyInvoiceDO finBillingApplyInvoiceDO = buildCondition(finBillingApplyInvoiceDTO);
        return finBillingApplyInvoiceMapper.selectList(finBillingApplyInvoiceDO).stream().map(t -> do2dto(t)).collect(Collectors.toList());
    }

    private FinBillingApplyInvoiceDO buildCondition(FinBillingApplyInvoiceDTO finBillingApplyInvoiceDTO) {
        return FinBillingApplyInvoiceDO.builder()
                .factoryCode(finBillingApplyInvoiceDTO.getFactoryCode())
                .receiptCode(finBillingApplyInvoiceDTO.getReceiptCode())
                .invoiceCode(finBillingApplyInvoiceDTO.getInvoiceCode())
                .finBillingApplyUid(finBillingApplyInvoiceDTO.getFinBillingApplyUid())
                .objuid(finBillingApplyInvoiceDTO.getObjuid()).build();
    }

    @Override
    public PageData<List<FinBillingApplyInvoiceDTO>> selectList(FinBillingApplyInvoiceDTO finBillingApplyInvoiceDTO, Integer limit, Integer curr) {
        Page<FinBillingApplyInvoiceDO> page = new Page<>(curr, limit);
        FinBillingApplyInvoiceDO finBillingApplyInvoiceDO = buildCondition(finBillingApplyInvoiceDTO);
        List<FinBillingApplyInvoiceDO> finBillingApplyInvoiceDOs = finBillingApplyInvoiceMapper.selectPageList(finBillingApplyInvoiceDO, page);
        List<FinBillingApplyInvoiceDTO> finBillingApplyDTOs = finBillingApplyInvoiceDOs.stream().map(t -> do2dto(t)).collect(Collectors.toList());
        return new PageData<>(((int) page.getTotal()), finBillingApplyDTOs);
    }
}
